# Forecast generator sourcing from Weatherbug.
# API docs: http://weather.weatherbug.com/desktop-weather/api-documents.html

import datetime
import logging
import urllib.request
import xml.etree.ElementTree as ET


from forecasts import common

class ForecastGen(common.ForecastGen):
    shortname = 'weatherbug'
    _baseurl = 'http://{key}.api.wxbug.net/\
getForecastRSS.aspx?ACode={key}&lat={lat}&long={lon}&UnitType=1&OutputType=1'

    def generate_url(self, latitude, longitude):
        with open('apikeys/weatherbug.key') as keyfile:
            apikey = keyfile.read().strip()
        self.url = self._baseurl.format(
            key=apikey, 
            lat=float(latitude), 
            lon=float(longitude))
        self.log.debug('URL: ' + self.url)

    def fetchdata(self, url=None):
        """Fetches the data from the web. 

        Returns a format suitable for use in processdata().
        """
        if url == None:
            url = self.url
        with urllib.request.urlopen(url) as f:
            data = ET.parse(f)
        return data

    def processdata(self, data):
        """data: an ElementTree

        This is the one function that heavily depends on the xml input being 
        as expected.
        """
        forecasts = {}
        xpath = '{http://www.aws.com/aws}forecasts/\
{http://www.aws.com/aws}forecast'
        fclist = data.findall(xpath)
        
        # Weatherbug only provides weekday names (Monday, Tuesday) as date
        # indicators, so we'll have to figure out what day today is in local
        # time. The first day in  the feed appears to be local today.
        firstday = fclist[0].findtext('{http://www.aws.com/aws}title')
        today = datetime.date.today()
        if firstday == (today+datetime.timedelta(days=1)).strftime('%A'):
            today += datetime.timedelta(days=1)
        elif firstday == (today-datetime.timedelta(days=1)).strftime('%A'):
            today -= datetime.timedelta(days=1)

        i = 1
        for forecast in fclist[1:]:
            try:
                forecasts[i] = common.Forecast(
                    today,
                    today + datetime.timedelta(days=i),
                    int(forecast.findtext('{http://www.aws.com/aws}low')),
                    int(forecast.findtext('{http://www.aws.com/aws}high'))
                    )
            except ValueError:
                # Weatherbug has shown "--" for temperatures in very few 
                # occasions, and only on the very last day.
                self.log.exception('Temperature not parseable, discarding \
forecast.')
            i += 1
        self.log.debug('Extracted {0} forecasts from the feed'.format(
            len(forecasts)))
        return forecasts

if __name__ == '__main__':
    logging.basicConfig(format='%(levelname)s-%(name)s: %(message)s', 
        level=logging.DEBUG)
    gen = ForecastGen(-37.02, 174.80)
    print(gen.getforecast(1))
    print(gen.getforecast(2))
    print(gen.getforecast(3))